import Vue from 'vue'
import Vuex from "vuex"
import lodash from 'lodash'

Vue.use(Vuex)
let store = new Vuex.Store({
    plugins: [
        function (store) {
            store.subscribe((mutation, state) => {
                sessionStorage.setItem('state', JSON.stringify(state))
            })
        }
    ]
})

function toGetOrSetName(stateName, prefix) {
    let firstChar = stateName.charAt(0)
    let firstCharUpper = firstChar.toUpperCase()
    let other = stateName.slice(1)
    return `${prefix}${firstCharUpper}${other}`
}

function initState(state, moduleName) {
    let stateKeys = Object.keys(state)
    for (let stateKey of stateKeys) {
        let stateInSession = sessionStorage.getItem('state')
        state[stateKey] = stateInSession ? JSON.parse(stateInSession)[moduleName][stateKey] : state[stateKey]
    }
}

function initGetters(getters, state) {
    let stateKeys = Object.keys(state)
    for (let stateKey of stateKeys) {
        let has = Object.keys(getters).includes(stateKey)
        if (!has) {
            getters[toGetOrSetName(stateKey, 'get')] = function (state) {
                return state[stateKey]
            }
        }
    }

}

function initMutations(mutations, state) {
    let stateKeys = Object.keys(state)
    for (let stateKey of stateKeys) {
        let has = Object.keys(mutations).includes(stateKey)
        if (!has) {
            mutations[toGetOrSetName(stateKey, 'set')] = function (state, payload) {
                state[stateKey] = payload
            }
        }
    }
}

function initReset(mutations, state, originState) {
    let has = Object.keys(mutations).includes('reset')
    if (!has) {
        mutations.reset = function (state) {
            let stateKeys = Object.keys(state)
            for (let stateKey of stateKeys) {
                state[stateKey] =  lodash.cloneDeep(originState[stateKey])
            }
        }
    }
}

let context = require.context('@/store', true, /\.js$/)
let keys = context.keys()
let keySet = new Set()
for (let key of keys) {
    let regexp = /\/([\w\-]+[^\/])\.js$/
    let fileName = regexp.exec(key)[1]
    if (keySet.has(fileName)) {
        throw new Error('store 初始化时出现相同的文件名称')
    }
    keySet.add(fileName)
    let module = context(key)

    let storeOption = module.storeOption
    let originState = module.state
    let state = storeOption.state

    initState(state, fileName)

    if (!storeOption.getters) {
        storeOption.getters = {}
    }
    let getters = storeOption.getters
    initGetters(getters, state)

    if (!storeOption.mutations) {
        storeOption.mutations = {}
    }
    let mutations = storeOption.mutations
    initMutations(mutations, state)
    initReset(mutations, state, originState)

    storeOption = {...storeOption, namespaced: true}
    store.registerModule(fileName, storeOption)
}

export {store}